package org.hbgl.geoentity.admin.web.admin;

import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.hbgl.geoentity.admin.annotation.OperationLog;
import org.hbgl.geoentity.admin.annotation.RequiresPermissionsDesc;
import org.hbgl.geoentity.admin.aspect.OperationType;
import org.hbgl.geoentity.admin.shiro.UserType;
import org.hbgl.geoentity.admin.util.Permission;
import org.hbgl.geoentity.admin.util.PermissionUtil;
import org.hbgl.geoentity.admin.vo.PermVo;
import org.hbgl.geoentity.admin.web.BaseController;
import org.hbgl.geoentity.core.util.JacksonUtil;
import org.hbgl.geoentity.core.util.ResponseUtil;
import org.hbgl.geoentity.core.validator.Order;
import org.hbgl.geoentity.core.validator.Sort;
import org.hbgl.geoentity.db.domain.GeRole;
import org.hbgl.geoentity.db.domain.GeUser;
import org.springframework.context.ApplicationContext;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.validation.constraints.NotNull;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import static org.hbgl.geoentity.admin.util.ResponseCode.*;

/**
 * 代码功能：角色管理
 * 开发日期：2022/4/26
 * 作者：蒋海仑
 * 联系方式：
 * 版本更迭说明：
 * 版权信息：河北广联信息技术有限公司
 */
@RestController
@RequestMapping("/admin/role")
@Validated
public class AdminRoleController extends BaseController {

    /**
     * 获取角色列表
     *
     * @param keywords 模糊查询
     * @param page     页码
     * @param limit    分页大小
     * @param sort     排序字段
     * @param order    排序方式
     */
    @RequiresPermissions("admin:role:list")
    @RequiresPermissionsDesc(menu = {"系统设置", "角色管理"}, button = "查询")
    @GetMapping("/list")
    public Object list(@RequestParam(defaultValue = "") String keywords,
                       @RequestParam(defaultValue = "1") Integer page,
                       @RequestParam(defaultValue = "10") Integer limit,
                       @Sort @RequestParam(defaultValue = "add_time") String sort,
                       @Order @RequestParam(defaultValue = "desc") String order) {
        GeUser userCurrent = getCurrentAdminUser();

        List<GeRole> roleList = roleService.allNormal(userCurrent.getUnitId(), keywords, page, limit, sort, order);
        for(GeRole item: roleList) {
            if(userCurrent.getRoleId().equals(item.getId())) {
                item.setIsOperate(1);
            }else {
                item.setIsOperate(0);
            }
        }
        return ResponseUtil.okList(roleList);
    }

    /**
     * 获取所有可用角色
     */
    @GetMapping("/all")
    public Object all() {
        GeUser userCurrent = getCurrentAdminUser();

        List<GeRole> roleList = roleService.allNormal(userCurrent.getUnitId());
        return ResponseUtil.ok(roleList);
    }

    /**
     * 根据角色ID获取角色信息
     *
     * @param id 角色ID
     */
    @RequiresPermissions("admin:role:detail")
    @RequiresPermissionsDesc(menu = {"系统设置", "角色管理"}, button = "详情")
    @GetMapping("/detail")
    public Object detail(@NotNull Integer id) {
        GeUser userCurrent = getCurrentAdminUser();

        GeRole roleLatest = roleService.findById(userCurrent.getUnitId(), id);
        if (roleLatest == null) {
            return ResponseUtil.badArgumentValue();
        }

        List<PermVo> systemPermissions = getSystemPermissions();
        Set<String> assignedPermissions = getAssignedPermissions(roleLatest.getId());

        Map<String, Object> data = new HashMap<>();
        data.put("role", roleLatest);
        data.put("systemPermissions", systemPermissions);
        data.put("assignedPermissions", assignedPermissions);

        return ResponseUtil.ok(data);
    }

    /**
     * 获取所有权限
     */
    @GetMapping("/permissions")
    public Object permissions() {
        List<PermVo> systemPermissions = getSystemPermissions();
        return ResponseUtil.ok(systemPermissions);
    }

    /**
     * 新建角色
     *
     * @param body { roleName : 角色名称, permissions : 已分配权限 }
     */
    @RequiresPermissions("admin:role:create")
    @RequiresPermissionsDesc(menu = {"系统设置", "角色管理"}, button = "新建")
    @OperationLog(detail = "新建角色", operationType = OperationType.INSERT, userType = UserType.ADMIN)
    @PostMapping("/create")
    public Object create(@RequestBody String body) {
        String roleName = JacksonUtil.parseString(body, "roleName");
        List<String> permissions = JacksonUtil.parseStringList(body, "permissions");
        if (!ObjectUtils.allNotNull(
                roleName, permissions
        )) {
            return ResponseUtil.badArgument();
        }
        if (StringUtils.isBlank(roleName) || CollectionUtils.isEmpty(permissions)) {
            return ResponseUtil.badArgumentValue();
        }

        GeUser userCurrent = getCurrentAdminUser();

        List<GeRole> userList = roleService.findByRoleName(userCurrent.getUnitId(), roleName);
        if (userList.size() > 0) {
            return ResponseUtil.fail(ROLE_NAME_EXIST, "角色已经存在");
        }

        GeRole role = new GeRole();
        role.setUnitId(userCurrent.getUnitId());
        role.setRoleName(roleName);
        roleService.add(role, permissions);

        return ResponseUtil.ok();
    }

    /**
     * 编辑角色信息
     *
     * @param body { id : 角色ID, roleName : 角色名称, permissions : 已分配权限 }
     */
    @RequiresPermissions("admin:role:update")
    @RequiresPermissionsDesc(menu = {"系统设置", "角色管理"}, button = "编辑")
    @OperationLog(detail = "编辑角色信息", operationType = OperationType.UPDATE, userType = UserType.ADMIN)
    @PostMapping("/update")
    public Object update(@RequestBody String body) {
        Integer id = JacksonUtil.parseInteger(body, "id");
        String roleName = JacksonUtil.parseString(body, "roleName");
        List<String> permissions = JacksonUtil.parseStringList(body, "permissions");
        if (!ObjectUtils.allNotNull(
                id, roleName, permissions
        )) {
            return ResponseUtil.badArgument();
        }
        if (StringUtils.isBlank(roleName) || CollectionUtils.isEmpty(permissions)) {
            return ResponseUtil.badArgumentValue();
        }

        GeUser userCurrent = getCurrentAdminUser();

        GeRole roleLatest = roleService.findById(userCurrent.getUnitId(), id);
        if (roleLatest == null) {
            return ResponseUtil.badArgumentValue();
        }

        List<GeRole> departmentList = roleService.findByRoleName(userCurrent.getUnitId(), roleName, id);
        if (departmentList.size() > 0) {
            return ResponseUtil.fail(ROLE_NAME_EXIST, "角色已经存在");
        }

        // 如果修改的角色是超级权限，则拒绝修改。
        if (permissionService.checkSuperPermission(id)) {
            return ResponseUtil.fail(ROLE_SUPER_SUPERMISSION, "当前角色的超级权限不能变更");
        }

        roleLatest.setRoleName(roleName);

        if (roleService.updateById(roleLatest, permissions) == 0) {
            return ResponseUtil.updatedDataFailed();
        }

        return ResponseUtil.ok();
    }

    /**
     * 根据角色ID删除角色信息
     *
     * @param body { id : 角色ID }
     */
    @RequiresPermissions("admin:role:delete")
    @RequiresPermissionsDesc(menu = {"系统设置", "角色管理"}, button = "删除")
    @OperationLog(detail = "删除角色", operationType = OperationType.DELETE, userType = UserType.ADMIN)
    @PostMapping("/delete")
    public Object delete(@RequestBody String body) {
        Integer id = JacksonUtil.parseInteger(body, "id");
        if (!ObjectUtils.allNotNull(
                id
        )) {
            return ResponseUtil.badArgument();
        }

        GeUser userCurrent = getCurrentAdminUser();

        if (userCurrent.getRoleId().equals(id)) {
            return ResponseUtil.fail(ROLE_DELETE_NOT_ALLOWED, "不能删除自己的角色");
        }

        // 如果当前角色所对应管理员仍存在，则拒绝删除角色。
        List<GeUser> userList = userService.all(userCurrent.getUnitId());
        for (GeUser user : userList) {
            // Integer[] roleIds = user.getRoleIds();
            // for (Integer roleId : roleIds) {
            //     if (id.equals(roleId)) {
            //         return ResponseUtil.fail(ROLE_USER_EXIST, "当前角色存在账号，不能删除");
            //     }
            // }
            if (id.equals(user.getRoleId())) {
                return ResponseUtil.fail(ROLE_USER_EXIST, "当前角色存在账号，不能删除");
            }
        }

        if (roleService.deleteByIdLogical(id) == 0) {
            return ResponseUtil.deletedDataFailed();
        }

        return ResponseUtil.ok();
    }

    @Resource
    private ApplicationContext context;
    private List<PermVo> systemPermissions = null;
    private Set<String> systemPermissionsString = null;

    private List<PermVo> getSystemPermissions() {
        final String basicPackage = "org.hbgl.geoentity.admin.web.admin";
        if (systemPermissions == null) {
            List<Permission> permissions = PermissionUtil.listPermission(context, basicPackage);
            systemPermissions = PermissionUtil.listPermVo(permissions);
            systemPermissionsString = PermissionUtil.listPermissionString(permissions);
        }
        return systemPermissions;
    }

    public Set<String> getAssignedPermissions(Integer roleId) {
        // 这里需要注意的是，如果存在超级权限*，那么这里需要转化成当前所有系统权限。
        // 之所以这么做，是因为前端不能识别超级权限，所以这里需要转换一下。
        Set<String> assignedPermissions;
        if (permissionService.checkSuperPermission(roleId)) {
            getSystemPermissions();
            assignedPermissions = systemPermissionsString;
        } else {
            assignedPermissions = permissionService.queryByRoleId(roleId);
        }

        return assignedPermissions;
    }

}
